﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MechanicCalculator.Utility;
using System.Reflection;
using System.Collections;

namespace MechanicCalculator
{
    public partial class MainForm : Form
    {
        private List<CalculatorData> calDataList = new List<CalculatorData>();
        private DatabaseManagement dbMgmt = new DatabaseManagement();
        private ExcelManagement excelMgmt = new ExcelManagement();
        private bool bChangedData = false;

        private TrialTimeManager trialChecker = new TrialTimeManager();

        private static readonly String CONST_TABLE_NAME = "MechanicInfo";
        private static readonly String CONST_SHEET_NAME = "[Sheet1$]";
        private int iRecordIdSelected = 0;
        public MainForm()
        {
            InitializeComponent();
            this.StartPosition = FormStartPosition.CenterScreen;
            InitUserInterface();


        }

        private void InitUserInterface()
        {
            #region Init User Interface
            comboBoxRecordIDs.Items.Add(1);
            comboBoxRecordIDs.SelectedIndex = 0;

            comboBoxFlangeClass.Items.Add(150);
            comboBoxFlangeClass.Items.Add(300);
            comboBoxFlangeClass.Items.Add(600);
            comboBoxFlangeClass.Items.Add(900);
            comboBoxFlangeClass.Items.Add(1500);
            comboBoxFlangeClass.Items.Add(2500);

            comboBoxNominalFlangeSize.Items.Add(0.5);
            comboBoxNominalFlangeSize.Items.Add(0.75);
            comboBoxNominalFlangeSize.Items.Add(1);
            comboBoxNominalFlangeSize.Items.Add(1.25);
            comboBoxNominalFlangeSize.Items.Add(1.5);
            comboBoxNominalFlangeSize.Items.Add(2);
            comboBoxNominalFlangeSize.Items.Add(2.5);
            comboBoxNominalFlangeSize.Items.Add(3);
            comboBoxNominalFlangeSize.Items.Add(3.5);
            comboBoxNominalFlangeSize.Items.Add(4);
            comboBoxNominalFlangeSize.Items.Add(5);
            comboBoxNominalFlangeSize.Items.Add(6);
            comboBoxNominalFlangeSize.Items.Add(8);
            comboBoxNominalFlangeSize.Items.Add(10);
            comboBoxNominalFlangeSize.Items.Add(12);
            comboBoxNominalFlangeSize.Items.Add(14);
            comboBoxNominalFlangeSize.Items.Add(16);
            comboBoxNominalFlangeSize.Items.Add(18);
            comboBoxNominalFlangeSize.Items.Add(20);
            for (int i = 24; i <= 60; i = i + 2)
            {
                comboBoxNominalFlangeSize.Items.Add(i);
            }

            comboBoxBoltGrade.Items.Add("ASTM A193 B7");
            comboBoxBoltGrade.Items.Add("ASTM A193 B16");
            comboBoxBoltGrade.Items.Add("ASTM A193 B7M");
            comboBoxBoltGrade.Items.Add("ASTM A320 Grade L7");

            comboBoxTargetOfYeild.Items.Add(25);
            comboBoxTargetOfYeild.Items.Add(50);
            comboBoxTargetOfYeild.Items.Add(75);

            comboBoxWrenchType.Items.Add("Square Drive");
            comboBoxWrenchType.Items.Add("Low Profile");

            comboBoxLubricant.Items.Add("Molykote 1000 (Molybdenum Disulfide) Grease");
            comboBoxLubricant.Items.Add("Moly / lead oxide /graphite");
            comboBoxLubricant.Items.Add("Machine Oil");
            comboBoxLubricant.Items.Add("Dry (New - First Use)");
            comboBoxLubricant.Items.Add("Dry (re-use)");
            comboBoxLubricant.Items.Add("HYTORC LoaDisc® & Molykote 321 Spray");
            comboBoxLubricant.Items.Add("HYTORC LoaDisc® & TS 801 Spray");
            comboBoxLubricant.Items.Add("Copper and Graphite");
            comboBoxLubricant.Items.Add("Nickel and Graphite");
            comboBoxLubricant.Items.Add("API SA Greases");
            comboBoxLubricant.Items.Add("Other");
            #endregion

            renewUI();
            trialChecker.SetNewDate();
            GlobalConstants.USAGE_TYPE ut = trialChecker.Expired();
            if (ut == GlobalConstants.USAGE_TYPE.LIMITED)
            {
                disableButtons();
            }
            else if (ut == GlobalConstants.USAGE_TYPE.EXIT)
            {
                Environment.Exit(0);
            }
            else if (ut == GlobalConstants.USAGE_TYPE.FULL)
            {
                enableButtons();
            }
            // Load Data From Database Insert into List<Calculator>
            // Iterate List<Calculator> and display on UI
            loadUIFromDatabase();
            bChangedData = false;

        }

        private void butExport_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDlg = new SaveFileDialog();
            saveFileDlg.Filter = "Excel File|*.xls";
            saveFileDlg.Title = "Save an Excel File";
            saveFileDlg.ShowDialog();

            // If the file name is not an empty string open it for saving.
            if (saveFileDlg.FileName != "")
            {
                // MessageBox.Show(saveFileDlg.FileName);
                // Save List<CalculatorData> to Database
                saveTempMemoryIntoDatabase();
                // Read Database
                String sql = String.Format("SELECT * FROM {0}", CONST_TABLE_NAME);
                DataTable dt = dbMgmt.GetDataTable(sql);
                // Create New Excel File
                excelMgmt.setStrExcelFileName(saveFileDlg.FileName);
                excelMgmt.CreateExcelFile();
                // Insert Data to Excel File
                int iCount = 1;
                foreach (DataRow dr in dt.Rows)
                {
                    Dictionary<String, String> data = new Dictionary<string, string>();
                    for (int i = 0; i < 11; i++)
                    {
                        if (i == 0)
                        {
                            data.Add("F1", iCount.ToString());
                        }
                        else
                        {
                            data.Add(String.Format("F{0}", i + 1), dr[i].ToString());
                        }
                    }
                    excelMgmt.Insert(CONST_SHEET_NAME, data);
                    iCount = iCount + 1;
                }
            }
        }

        private void butImport_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDlg = new OpenFileDialog();
            openFileDlg.Filter = "Excel Files (.xls)|*.xls|All Files (*.*)|*.*";
            openFileDlg.FilterIndex = 1;

            openFileDlg.Multiselect = false;
            if (openFileDlg.ShowDialog() == DialogResult.OK)
            {
                // MessageBox.Show(openFileDlg.FileName);
                // Read Excel File
                excelMgmt.setStrExcelFileName(openFileDlg.FileName);
                String sql = String.Format("SELECT * FROM {0}", CONST_SHEET_NAME);
                DataTable dt = excelMgmt.GetDataTable(sql);
                // Clean ALL Sql Database
                dbMgmt.ClearTable(CONST_TABLE_NAME);
                // Clean Temp Data
                calDataList.Clear();
                // Insert Into SQL Database
                bool bFirst = true;
                foreach (DataRow dr in dt.Rows)
                {
                    if (!bFirst)
                    {
                        Dictionary<String, String> data = new Dictionary<string, string>();
                        for (int i = 0; i < ExcelManagement.COLUMN_NAMES.Length; i++)
                        {
                            data.Add(ExcelManagement.COLUMN_NAMES[i], dr[i + 1].ToString());
                        }
                        dbMgmt.Insert(CONST_TABLE_NAME, data);
                    }
                    bFirst = false;
                }
                // Load Database into List<CalculatorData>
                // Change GUI or Load GUI
                loadUIFromDatabase();
            }
        }

        private void btnNewRecord_Click(object sender, EventArgs e)
        {
            // Add new item into comboBox Index Record
            int iCount = comboBoxRecordIDs.Items.Count;
            comboBoxRecordIDs.Items.Add(iCount + 1);
            comboBoxRecordIDs.SelectedIndex = iCount;

            CalculatorData calData = new CalculatorData();
            calDataList.Add(calData);
            // Renew UI
            renewUI();
            bChangedData = true;
        }

        private void btnDeleteRecord_Click(object sender, EventArgs e)
        {
            int iCur = comboBoxRecordIDs.SelectedIndex;
            if (comboBoxRecordIDs.Items.Count > 1)
            {
                // Delete current index of combox Box
                calDataList.RemoveAt(iCur);
                //comboBoxRecordIDs.Items.RemoveAt(iCur);
                comboBoxRecordIDs.Items.RemoveAt(comboBoxRecordIDs.Items.Count-1);
                // Change to previous/next index of combox Box
                if (iCur - 1 >= 0)
                {
                    comboBoxRecordIDs.SelectedIndex = iCur - 1;
                }
                else
                {
                    comboBoxRecordIDs.SelectedIndex = 0;
                }
                bChangedData = true;
            }
            else
            {
                // At least one record exist
                MessageBox.Show("At least one record must be existed", "WARNING", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        private void buttonSaveDatabase_Click(object sender, EventArgs e)
        {
            // Save to Database SQLite
            if (bChangedData)
            {
                saveTempMemoryIntoDatabase();
                MessageBox.Show("Save to Database successfully", "Save To DB", MessageBoxButtons.OK, MessageBoxIcon.Information);
                bChangedData = false;
            }
            else
            {
                MessageBox.Show("Nothing to save", "Save To DB", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void renewUI()
        {
            btnMeasureInch.ForeColor = Color.Red;
            btnMeasureMetric.ForeColor = SystemColors.WindowFrame;

            btnMeasureAnsi.ForeColor = Color.Red;
            btnMeasureAPI.ForeColor = SystemColors.WindowFrame;

            comboBoxFlangeClass.SelectedIndex = 0;
            comboBoxNominalFlangeSize.SelectedIndex = 0;
            comboBoxBoltGrade.SelectedIndex = 0;
            comboBoxTargetOfYeild.SelectedIndex = 0;
            radioButtonFour.Checked = true;
            radioButtonTwo.Checked = false;
            radioButtonOne.Checked = false;
            comboBoxWrenchType.SelectedIndex = 0;
            radioButtonLoaDiscYes.Checked = false;
            radioButtonLoaDiscNo.Checked = true;
            comboBoxLubricant.SelectedIndex = 0;

        }

        // Disable Button for License
        private void disableButtons()
        {
            btnNewRecord.Enabled = false;
            btnDeleteRecord.Enabled = false;
            btnSaveDatabase.Enabled = false;
            butImport.Enabled = false;
            butExport.Enabled = false;
            btnCalculate.Enabled = false;
            // btnUpgrade.Enabled = true;
        }

        private void enableButtons()
        {
            btnNewRecord.Enabled = true;
            btnDeleteRecord.Enabled = true;
            btnSaveDatabase.Enabled = true;
            butImport.Enabled = true;
            butExport.Enabled = true;
            btnCalculate.Enabled = true;
            // btnUpgrade.Enabled = false;
        }

        private void saveTempMemoryIntoDatabase()
        {
            dbMgmt.ClearTable(CONST_TABLE_NAME);
            foreach (CalculatorData calData in calDataList)
            {
                Dictionary<String, String> data = new Dictionary<string, string>();
                data.Add(ExcelManagement.MEASURE_SYSTEM_LENGTH, calData.MeasureSystemLength);
                data.Add(ExcelManagement.MEASURE_SYSTEM_PRESSURE, calData.MeasureSystemPressure);
                data.Add(ExcelManagement.FLANGE_CLASS, calData.FlangeClass);
                data.Add(ExcelManagement.NOMINAL_FLANGE_SIZE, calData.NominalFlangeSize);
                data.Add(ExcelManagement.BOLT_GRADE, calData.BoltGrade);
                data.Add(ExcelManagement.TARGET_PERCENT_OF_YIELD, calData.TargetPercentOfYield);
                data.Add(ExcelManagement.NUMBER_OF_TOOLS, calData.NumberOfTools);
                data.Add(ExcelManagement.WRENCH_TYPE, calData.WrenchType);
                data.Add(ExcelManagement.LOA_DISC, calData.LoaDisc);
                data.Add(ExcelManagement.LUBRICANT, calData.Lubricant);
                dbMgmt.Insert(CONST_TABLE_NAME, data);
            }
        }

        private void loadDataFromDatabaseIntoTempMemory()
        {
            String sql = String.Format("SELECT * FROM {0}", CONST_TABLE_NAME);
            DataTable dt = dbMgmt.GetDataTable(sql);
            if (dt.Rows.Count > 0)
            {
                foreach (DataRow dr in dt.Rows)
                {
                    CalculatorData calData = new CalculatorData();
                    calData.MeasureSystemLength = dr[1].ToString();
                    calData.MeasureSystemPressure = dr[2].ToString();
                    calData.FlangeClass = dr[3].ToString();
                    calData.NominalFlangeSize = dr[4].ToString();
                    calData.BoltGrade = dr[5].ToString();
                    calData.TargetPercentOfYield = dr[6].ToString();
                    calData.NumberOfTools = dr[7].ToString();
                    calData.WrenchType = dr[8].ToString();
                    calData.LoaDisc = dr[9].ToString();
                    calData.Lubricant = dr[10].ToString();
                    calDataList.Add(calData);
                }
            }
            else
            {
                CalculatorData calData = new CalculatorData();
                calDataList.Add(calData);
            }
        }

        private void loadUIFromTempMemory(int index, bool isReloadComboBoxRecordIds)
        {
            if (isReloadComboBoxRecordIds)
            {
                if (comboBoxRecordIDs.Items.Count > 0 && calDataList.Count > 0)
                {
                    comboBoxRecordIDs.Items.Clear();
                }
                for (int i = 0; i < calDataList.Count; i++)
                {
                    comboBoxRecordIDs.Items.Add(i + 1);
                }
                comboBoxRecordIDs.SelectedIndex = 0;
            }

            CalculatorData calData = calDataList[index];
            if (calData.MeasureSystemLength.Equals(CalculatorData.CONST_MEASURE_SYSTEM_INCH))
            {
                btnMeasureInch.ForeColor = Color.Red;
                btnMeasureMetric.ForeColor = SystemColors.WindowFrame;
            }
            else
            {
                btnMeasureInch.ForeColor = Color.Silver;
                btnMeasureMetric.ForeColor = Color.Red;
            }

            if (calData.MeasureSystemPressure.Equals(CalculatorData.CONST_MEASURE_SYSTEM_ANSI))
            {
                btnMeasureAnsi.ForeColor = Color.Red;
                btnMeasureAPI.ForeColor = SystemColors.WindowFrame;
            }
            else
            {
                btnMeasureAnsi.ForeColor = Color.Silver;
                btnMeasureAPI.ForeColor = Color.Red;
            }
            for (int i = 0; i < comboBoxFlangeClass.Items.Count; i++)
            {
                if (calData.FlangeClass.Equals(comboBoxFlangeClass.Items[i].ToString()))
                {
                    comboBoxFlangeClass.SelectedIndex = i;
                }
            }

            for (int i = 0; i < comboBoxNominalFlangeSize.Items.Count; i++)
            {
                if (calData.NominalFlangeSize.Equals(comboBoxNominalFlangeSize.Items[i].ToString()))
                {
                    comboBoxNominalFlangeSize.SelectedIndex = i;
                }
            }

            for (int i = 0; i < comboBoxBoltGrade.Items.Count; i++)
            {
                if (calData.BoltGrade.Equals(comboBoxBoltGrade.Items[i].ToString()))
                {
                    comboBoxBoltGrade.SelectedIndex = i;
                }
            }

            for (int i = 0; i < comboBoxTargetOfYeild.Items.Count; i++)
            {
                if (calData.TargetPercentOfYield.Equals(comboBoxTargetOfYeild.Items[i].ToString()))
                {
                    comboBoxTargetOfYeild.SelectedIndex = i;
                }
            }

            int numberOfTools = Convert.ToInt32(calData.NumberOfTools);
            switch (numberOfTools)
            {
                case 1:
                    radioButtonFour.Checked = false;
                    radioButtonTwo.Checked = false;
                    radioButtonOne.Checked = true;
                    break;
                case 2:
                    radioButtonFour.Checked = false;
                    radioButtonTwo.Checked = true;
                    radioButtonOne.Checked = false;
                    break;
                case 4:
                    radioButtonFour.Checked = true;
                    radioButtonTwo.Checked = false;
                    radioButtonOne.Checked = false;
                    break;
            }
            for (int i = 0; i < comboBoxWrenchType.Items.Count; i++)
            {
                if (calData.WrenchType.Equals(comboBoxWrenchType.Items[i].ToString()))
                {
                    comboBoxWrenchType.SelectedIndex = i;
                }
            }

            //bool loaDisc = Convert.ToBoolean(calData.LoaDisc);
            if (calData.LoaDisc.Equals("true"))
            {
                radioButtonLoaDiscYes.Checked = true;
                radioButtonLoaDiscNo.Checked = false;
            }
            else
            {
                radioButtonLoaDiscYes.Checked = false;
                radioButtonLoaDiscNo.Checked = true;
            }

            for (int i = 0; i < comboBoxLubricant.Items.Count; i++)
            {
                if (calData.Lubricant.Equals(comboBoxLubricant.Items[i].ToString()))
                {
                    comboBoxLubricant.SelectedIndex = i;
                }
            }
        }

        private void loadUIFromDatabase()
        {
            loadDataFromDatabaseIntoTempMemory();
            if (calDataList.Count > 0)
                loadUIFromTempMemory(0, true);
        }

        #region Update UI into temp memory
        private void btnMeasureInch_Click(object sender, EventArgs e)
        {
            btnMeasureInch.ForeColor = Color.Red;
            btnMeasureMetric.ForeColor = SystemColors.WindowFrame;

            calDataList[iRecordIdSelected].MeasureSystemLength = CalculatorData.CONST_MEASURE_SYSTEM_INCH;

            bChangedData = true;
        }

        private void btnMeasureMetric_Click(object sender, EventArgs e)
        {
            btnMeasureInch.ForeColor = Color.Silver;
            btnMeasureMetric.ForeColor = Color.Red;

            calDataList[iRecordIdSelected].MeasureSystemLength = CalculatorData.CONST_MEASURE_SYSTEM_METRIC;

            bChangedData = true;
        }

        private void btnMeasureAnsi_Click(object sender, EventArgs e)
        {
            btnMeasureAnsi.ForeColor = Color.Red;
            btnMeasureAPI.ForeColor = SystemColors.WindowFrame;

            calDataList[iRecordIdSelected].MeasureSystemPressure = CalculatorData.CONST_MEASURE_SYSTEM_ANSI;

            bChangedData = true;
        }

        private void btnMeasureAPI_Click(object sender, EventArgs e)
        {
            btnMeasureAnsi.ForeColor = Color.Silver;
            btnMeasureAPI.ForeColor = Color.Red;

            calDataList[iRecordIdSelected].MeasureSystemPressure = CalculatorData.CONST_MEASURE_SYSTEM_API;

            bChangedData = true;
        }

        private void comboBoxFlangeClass_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (calDataList.Count > 0)
            {
                calDataList[iRecordIdSelected].FlangeClass = comboBoxFlangeClass.Items[comboBoxFlangeClass.SelectedIndex].ToString();

                bChangedData = true;
            }
        }

        private void comboBoxNominalFlangeSize_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (calDataList.Count > 0)
            {
                calDataList[iRecordIdSelected].NominalFlangeSize = comboBoxNominalFlangeSize.Items[comboBoxNominalFlangeSize.SelectedIndex].ToString();

                bChangedData = true;
            }
        }

        private void comboBoxBoltGrade_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (calDataList.Count > 0)
            {
                calDataList[iRecordIdSelected].BoltGrade = comboBoxBoltGrade.Items[comboBoxBoltGrade.SelectedIndex].ToString();

                bChangedData = true;
            }
        }

        private void comboBoxTargetOfYeild_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (calDataList.Count > 0)
            {
                calDataList[iRecordIdSelected].TargetPercentOfYield = comboBoxTargetOfYeild.Items[comboBoxTargetOfYeild.SelectedIndex].ToString();

                bChangedData = true;
            }
        }

        private void radioButtonFour_CheckedChanged(object sender, EventArgs e)
        {
            calDataList[iRecordIdSelected].NumberOfTools = "4";
            bChangedData = true;
        }

        private void radioButtonTwo_CheckedChanged(object sender, EventArgs e)
        {
            calDataList[iRecordIdSelected].NumberOfTools = "2";
            bChangedData = true;
        }

        private void radioButtonOne_CheckedChanged(object sender, EventArgs e)
        {
            calDataList[iRecordIdSelected].NumberOfTools = "1";
            bChangedData = true;
        }

        private void comboBoxWrenchType_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (calDataList.Count > 0)
            {
                calDataList[iRecordIdSelected].WrenchType = comboBoxWrenchType.Items[comboBoxWrenchType.SelectedIndex].ToString();
                bChangedData = true;
            }
        }

        private void radioButtonLoaDiscYes_CheckedChanged(object sender, EventArgs e)
        {
            calDataList[iRecordIdSelected].LoaDisc = "true";
            bChangedData = true;
        }

        private void radioButtonLoaDiscNo_CheckedChanged(object sender, EventArgs e)
        {
            calDataList[iRecordIdSelected].LoaDisc = "false";
            bChangedData = true;
        }

        private void comboBoxLubricant_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (calDataList.Count > 0)
            {
                calDataList[iRecordIdSelected].Lubricant = comboBoxLubricant.Items[comboBoxLubricant.SelectedIndex].ToString();
                bChangedData = true;
            }
        }
        #endregion

        private void comboBoxRecordIDs_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (calDataList.Count > 0 && comboBoxRecordIDs.SelectedIndex < calDataList.Count)
            {
                iRecordIdSelected = comboBoxRecordIDs.SelectedIndex;
                loadUIFromTempMemory(comboBoxRecordIDs.SelectedIndex, false);
            }
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            // Display a MsgBox asking the user to save changes or abort.
            if (bChangedData)
            {
                if (MessageBox.Show("Do you want to save changes?", "Flange Pattern Calculation",
                   MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    // Cancel the Closing event from closing the form.
                    // e.Cancel = true;
                    // Call method to save file...
                    saveTempMemoryIntoDatabase();
                    MessageBox.Show("Save to Database successfully", "Save To DB", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
        }

        private void btnUpgrade_Click(object sender, EventArgs e)
        {
            SerialDialog serialDialog = new SerialDialog();
            DialogResult serialResult = serialDialog.ShowDialog();
            if (serialResult == DialogResult.OK)
            {

                enableButtons();
                MessageBox.Show("Successfully registered", "WOW");
                using (Microsoft.Win32.RegistryKey key =
            Microsoft.Win32.Registry.CurrentUser.CreateSubKey(@"SOFTWARE\Test"))
                {
                    key.SetValue("Date", "-1", Microsoft.Win32.RegistryValueKind.String);
                }

            }
        }
    }
}
